#include "stats.h"

Stats::Stats () : data ()
{
}

Stats::Stats (const Numvec& vec) : data ()
{
  data = vec;
}

void Stats::add_vec (const Numvec& vec)
{
  data = vec;
}

int Stats::item_num ()
{
  return res.items = data.pos;
}

float Stats::max ()
{
  res.max_val = MINFLOAT;              // smallest value for a float
  for (int i = 0; i < data.pos; i++)
	if (data.data_vec[i] > res.max_val)
	  res.max_val = data.data_vec[i];
  return res.max_val;
}

float Stats::min ()
{
  res.min_val = MAXFLOAT;              // largest value for a float
  for (int i = 0; i < data.pos; i++)
	if (data.data_vec[i] < res.min_val)
	  res.min_val = data.data_vec[i];
  return res.min_val;
}

float Stats::mean ()
{
  float sum = 0;
  for (int i = 0; i < data.pos; i++)
	sum += data.data_vec[i];
  return res.average = sum / data.pos;
}

float Stats::median ()
{
  int gap, i;
  float *temp, swap_var, sum = 0;

  temp = new float[data.pos];
  for (i = 0; i < data.pos; i++)
	temp[i] = data.data_vec[i];

  gap = data.pos / 2;
  while (gap >= 1)
  {
	for (i = 0; i < data.pos - gap; i++)
	  if (temp[i] < temp[i + gap])
	  {
		swap_var = temp[i];
		temp[i] = temp[i + gap];
		temp[i + gap] = swap_var;
	  }
	gap /= 2;
  }

  if ((data.pos % 2) == 1)
  {
	i = floor (data.pos / 2);
	return res.median_val = temp[i];
  }
  else
  {
	i = data.pos / 2 - 1;
	sum = temp[i];
	sum += temp[++i];
	return res.median_val = sum / 2;
  }
}

float Stats::variance ()
{
  float sum = 0, temp;

  mean ();
  for (int i = 0; i < data.pos; i++)
  {
	temp = data.data_vec[i] - res.average;
	sum += (temp * temp);
  }
  return res.variant = sum / (data.pos - 1);
}

double Stats::deviation ()
{
  variance ();
  return res.sd = sqrt (res.variant);
}

void Stats::print ()
{
  item_num ();
  max ();
  min ();
  mean ();
  median ();
  variance ();
  deviation ();

  cout << "Statistical results for " << data.name << ": " << endl;
  cout << "Number of items in the vector: " << res.items << endl;
  cout << "Maxinum value: " << res.max_val << endl;
  cout << "Mininum value: " << res.min_val << endl;
  cout << "Average value: " << res.average << endl;
  cout << "Median value: " << res.median_val << endl;
  cout << "Variance: " << res.variant << endl;
  cout << "Standard Deviation: " << res.sd << endl;
}
